package com.gitee.wsl.common.chart.adapter

import com.gitee.wsl.common.chart.api.ChartDatasetChangeListenerContain
import com.gitee.wsl.common.chart.listener.ChartDatasetChangeListener
import com.gitee.wsl.common.chart.listener.ChartSelectListener
import com.gitee.wsl.common.chart.listener.click.PositionRecord
import com.gitee.wsl.ext.list.notInIndex
import com.gitee.wsl.ext.list.setAll
import timber.log.Timber

abstract class AbstractChartAdapter<T,P: PositionRecord>: com.gitee.wsl.common.ui.api.ObjectSelectAble<List<P>>,
    com.gitee.wsl.common.ui.api.TouchCheckAble,
    com.gitee.wsl.common.ui.api.SelectListenerContainer<ChartSelectListener<P>>, ChartDatasetChangeListenerContain<ChartDatasetChangeListener<T>> {

    //数据源
    val dataset = mutableListOf<T>()

    val noSelectDataSet : List<T>
        get() {
           return if(!isTouched())
                     dataset
                  else
                     dataset.filter { !isSelectItem(it)  }
        }

    //数据对应位置
    val recordset = mutableListOf<P>()

    //当前选择对像
    val selectRecordSet =  mutableListOf<P>()

    var isRecordSetInited = false


    override val selectListenerList:MutableList<ChartSelectListener<P>> = mutableListOf()

    override val datasetChangeListenerList :MutableList<ChartDatasetChangeListener<T>> = mutableListOf()

    fun setDataSource(newDataSource:List<T>){
        if(dataset.isEmpty() && newDataSource.isEmpty()) return

        val oldList=dataset.toList()
        dataset.setAll(newDataSource)
        datasetChangeListenerList.forEach {
            it.onDatasetChanged(oldList,newDataSource)
        }

        initState()
    }

    private fun initState(){
        recordset.clear()
        selectRecordSet.clear()
        isRecordSetInited=false
    }

    override fun selectObject(x: Float, y: Float): List<P>? {
        val select= mutableListOf<P>()
        recordset.forEach {
            if(it.compareRange(x,y)) select.add(it)
        }
        Timber.d("selectObject touchX:$x,touchY:$y,select:${select.size}")
        return select
    }

    fun isSelectItem(item:T):Boolean{
        if(!isTouched()) return false
        val index = dataset.indexOf(item)
        return selectRecordSet[0].dataID == index
    }

    fun selectItem(item:T):Boolean{
        if(isSelectItem(item)) return false
        val dataIndex=dataset.indexOf(item)
        recordset.forEach {
            if(it.dataID == dataIndex) {
                selectRecordSet.setAll(listOf(it))
                return true
            }
        }
        return false
    }

    fun selectItemUseIndex(index:Int):Boolean{
        if(dataset.notInIndex(index)) return false
        return selectItem(dataset[index])
    }

    override fun isTouched():Boolean  = selectRecordSet.isNotEmpty()

    override fun callTouchListener(){
        if(!isTouched()) return
        selectListenerList.forEach {
            val obj = selectRecordSet[0]
            it.onClick(obj)
        }
    }

    override fun checkTouch(touchX:Float, touchY:Float):Boolean{
        clearTouch()
        selectObject(touchX,touchY)?.let {
            selectRecordSet.setAll(it)
        }
        return isTouched()
    }

    override fun clearTouch(){
        selectRecordSet.clear()
    }

}

